package annotations;

import java.awt.event.*;
import java.lang.reflect.*;

/**
 * @version 1.00 2004-08-17
 * @author Cay Horstmann
 */
public class ActionListenerInstaller {
   /**
    * Processes all ActionListenerFor annotations in the given object.
    * @param obj an object whose methods may have ActionListenerFor annotations
    */
   public static void processAnnotations(Object obj) {
      try {
         Class<?> cl = obj.getClass();
         for (Method m : cl.getDeclaredMethods()) {
            //检查使用ActionListenerFor注解的方法并将其加入监听列表中
            ActionListenerFor a = m.getAnnotation(ActionListenerFor.class);
            if (a != null) {
               Field f = cl.getDeclaredField(a.source());
               f.setAccessible(true);
               //将方法加入监听中
               addListener(f.get(obj), obj, m);
            }
         }
      } catch(ReflectiveOperationException e){
         e.printStackTrace();
      }
   }

   /**
    * Adds an action listener that calls a given method.
    * @param source the event source to which an action listener is added
    * @param param the implicit parameter of the method that the listener calls
    * @param m the method that the listener calls
    */
   public static void addListener(Object source, final Object param, final Method m) throws ReflectiveOperationException {

      InvocationHandler handler = new InvocationHandler() {
            public Object invoke(Object proxy, Method mm, Object[] args) throws Throwable {
               return m.invoke(param);
            }
         };
      //获取代理对象
      Object listener = Proxy.newProxyInstance(null,new Class[] { ActionListener.class }, handler);
      Method adder = source.getClass().getMethod("addActionListener", ActionListener.class);
      //加入监听
      adder.invoke(source, listener);
   }
}
